﻿#region Copyright (c) 2011, thinktecture (http://www.thinktecture.com)

/*
   thinktecture.UIAnnotations was developed by Jörg Neumann.
   Copyright (c) 2011, thinktecture (http://www.thinktecture.com).
   All rights reserved, comes as-is and without any warranty. Use of this
   source file is governed by the license which is contained in LICENSE.TXT 
   in the distribution.
*/

#endregion

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace Thinktecture.DataForm
{
    [TemplatePart(Name = "PART_Image", Type=typeof(Image))]
    public class Marker : Control
    {
        private Image _image;

        static Marker()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Marker), new FrameworkPropertyMetadata(typeof(Marker)));
        }
        public Marker()
        {
            Uri resourceLocater =
                new Uri("/Thinktecture.DataForm;component/Themes/generic.xaml", UriKind.Relative);
            ResourceDictionary dict = Application.LoadComponent(resourceLocater) as ResourceDictionary;
            this.Template = dict["MarkerTemplate"] as ControlTemplate;
            this.Focusable = false;
        }

        public override void OnApplyTemplate()
        {
            _image = this.Template.FindName("PART_Image", this) as Image;
            base.OnApplyTemplate();
        }

        #region MarkerType

        public static readonly DependencyProperty MarkerTypeProperty =
            DependencyProperty.Register("MarkerType", typeof(MarkerType), typeof(Marker), new FrameworkPropertyMetadata(MarkerType.None, FrameworkPropertyMetadataOptions.AffectsRender, OnMarkerTypePropertyChanged));
        public MarkerType MarkerType { get { return (MarkerType)GetValue(MarkerTypeProperty); } set { SetValue(MarkerTypeProperty, value); } }

        private static void OnMarkerTypePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ((Marker)sender).OnMarkerTypeChanged(sender, e);
        }

        private void OnMarkerTypeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            switch ((MarkerType)e.NewValue)
            {
                case MarkerType.EditTracker:
                    if (this.EditTrackerImage != null)
                    {
                        this.CurrentImage = this.EditTrackerImage;
                        this.Scaling = 1;
                    }
                    else
                    {
                        this.CurrentImage = this.GetMarkerImage();
                        this.Scaling = 1d;
                    }
                    break;
                case MarkerType.FieldTracker:
                    if (this.FieldTrackerImage != null)
                    {
                        this.CurrentImage = this.FieldTrackerImage;
                        this.Scaling = 1;
                    }
                    else
                    {
                        this.CurrentImage = this.GetMarkerImage();
                        this.Scaling = 0.9d;
                    }
                    break;
                case MarkerType.RequiredField:
                    if (this.RequiredFieldImage != null)
                    {
                        this.CurrentImage = this.RequiredFieldImage;
                        this.Scaling = 1;
                    }
                    else
                    {
                        this.CurrentImage = this.GetMarkerImage();
                        this.Scaling = 0.5d;
                    }
                    break;
                case MarkerType.Error:
                    if (this.ErrorImage != null)
                    {
                        this.CurrentImage = this.ErrorImage;
                        this.Scaling = 1;
                    }
                    else
                    {
                        this.CurrentImage = this.GetMarkerImage();
                        this.Scaling = 1.1d;
                    }
                    break;
                default:
                    this.CurrentImage = this.GetMarkerImage();
                    this.Scaling = 1;
                    break;
            }
        }

        #endregion

        #region Scaling

        public static readonly DependencyProperty ScalingProperty =
            DependencyProperty.Register("Scaling", typeof(double), typeof(Marker), new UIPropertyMetadata(1d));
        public double Scaling { get { return (double)GetValue(ScalingProperty); } set { SetValue(ScalingProperty, value); } }

        #endregion

        #region EditTrackerImage

        public static readonly DependencyProperty EditTrackerImageProperty =
            DependencyProperty.Register("EditTrackerImage", typeof(ImageSource), typeof(Marker));
        public ImageSource EditTrackerImage { get { return (ImageSource)GetValue(EditTrackerImageProperty); } set { SetValue(EditTrackerImageProperty, value); } }

        #endregion

        #region FieldTrackerImage

        public static readonly DependencyProperty FieldTrackerImageProperty =
            DependencyProperty.Register("FieldTrackerImage", typeof(ImageSource), typeof(Marker));
        public ImageSource FieldTrackerImage { get { return (ImageSource)GetValue(FieldTrackerImageProperty); } set { SetValue(FieldTrackerImageProperty, value); } }

        #endregion

        #region ErrorImage

        public static readonly DependencyProperty ErrorImageProperty =
            DependencyProperty.Register("ErrorImage", typeof(ImageSource), typeof(Marker));
        public ImageSource ErrorImage { get { return (ImageSource)GetValue(ErrorImageProperty); } set { SetValue(ErrorImageProperty, value); } }

        #endregion

        #region RequiredFieldImage

        public static readonly DependencyProperty RequiredFieldImageProperty =
            DependencyProperty.Register("RequiredFieldImage", typeof(ImageSource), typeof(Marker));
        public ImageSource RequiredFieldImage { get { return (ImageSource)GetValue(RequiredFieldImageProperty); } set { SetValue(RequiredFieldImageProperty, value); } }

        #endregion
        
        #region CurrentImage

        public static readonly DependencyProperty CurrentImageProperty =
            DependencyProperty.Register("CurrentImage", typeof(ImageSource), typeof(Marker));
        public ImageSource CurrentImage { get { return (ImageSource)GetValue(CurrentImageProperty); } set { SetValue(CurrentImageProperty, value); } }

        #endregion

        private ImageSource GetMarkerImage()
        {
            var type = this.MarkerType;
            Uri resourceLocater =
                new Uri("/Thinktecture.DataForm;component/Themes/generic.xaml", UriKind.Relative);
            ResourceDictionary dict = Application.LoadComponent(resourceLocater) as ResourceDictionary;
            object resource = null;
            switch (type)
            {
                case MarkerType.None:
                    resource = dict["NoneMarker"];
                    break;
                case MarkerType.EditTracker:
                    resource = dict["EditTracker"];
                    break;
                case MarkerType.FieldTracker:
                    resource = dict["FieldTracker"];
                    break;
                case MarkerType.RequiredField:
                    resource = dict["RequiredFieldMarker"];
                    break;
                case MarkerType.Error:
                    resource = dict["ErrorMarker"];
                    break;
            }
            var drawing = resource as Drawing;
            return new DrawingImage(drawing);
        }
    }

    public enum MarkerType
    {
        None,
        EditTracker,
        FieldTracker,
        RequiredField,
        Error
    }
}
